﻿/**
 * Copyright (C) 2001 Yasna.com. All rights reserved.
 *
 * ===================================================================
 * The Apache Software License, Version 1.1
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by
 *        Yasna.com (http://www.yasna.com)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Yazd" and "Yasna.com" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please
 *    contact yazd@yasna.com.
 *
 * 5. Products derived from this software may not be called "Yazd",
 *    nor may "Yazd" appear in their name, without prior written
 *    permission of Yasna.com.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL YASNA.COM OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of Yasna.com. For more information
 * on Yasna.com, please see <http://www.yasna.com>.
 */

/**
 * Copyright (C) 2000 CoolServlets.com. All rights reserved.
 *
 * ===================================================================
 * The Apache Software License, Version 1.1
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by
 *        CoolServlets.com (http://www.coolservlets.com)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Jive" and "CoolServlets.com" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please
 *    contact webmaster@coolservlets.com.
 *
 * 5. Products derived from this software may not be called "Jive",
 *    nor may "Jive" appear in their name, without prior written
 *    permission of CoolServlets.com.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL COOLSERVLETS.COM OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of CoolServlets.com. For more information
 * on CoolServlets.com, please see <http://www.coolservlets.com>.
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using JiveCsharp.Common;
using JiveCsharp.Common.Permissions;
using JiveCsharp.Model.Filter;

namespace JiveCsharp.Model
{
    public interface Forum
    {
        //used for sorting the threads
        //public  const int SORT_BY_CREATE_DATE = 0;
        //public  const int SORT_BY_MODIFIED_DATE = 1;


        /// <summary>
        /// the unique id of the forum.
        /// </summary>
        int ID { get; }

        /// <summary>
        /// the name of the forum.
        /// </summary>
        /// <exception cref="UnauthorizedException,ForumAlreadyExistsException">
        /// throws UnauthorizedException if does not have ADMIN permissions.
        /// throws ForumAlreadyExistsException if a forum with the specified name already exists.
        /// </exception>
        String Name { get; set; }

        /// <summary>
        /// the description of the forum
        /// </summary>
        /// <exception cref="UnauthorizedException">
        /// throws UnauthorizedException if does not have ADMIN permissions
        /// </exception>
        String Description { get; set; }


        /// <summary>
        ///  the Date that the forum was created.
        /// </summary>
        /// <exception cref="UnauthorizedException">
        /// throws UnauthorizedException if does not have ADMIN permissions
        /// </exception>
        /// <remarks>
        ///  In most cases, the creation date
        ///  will default to when the forum was entered into the system. However,
        ///  the creation date needs to be set manually when importing data.
        ///  In other words, skin authors should ignore this method since it only
        ///  intended for system maintenance.
        /// </remarks>
        DateTime CreationDate { get; set; }




        /// <summary>
        /// the Date that the forum was last modified.
        /// </summary>
        /// <exception cref="UnauthorizedException">
        /// throws UnauthorizedException if does not have ADMIN permissions
        /// </exception>
        /// <remarks>
        /// In other words, the date of the most recent message or thread in the forum.
        /// Sets the date the forum was last modified. In most cases, last modifed
        /// will default to when the forum data was last changed. However,
        /// the last modified date needs to be set manually when importing data.
        /// In other words, skin authors should ignore this method since it only
        /// intended for system maintenance.
        /// </remarks>
        DateTime ModifiedDate { get; set; }

        /// <summary>
        /// an extended property of the forum.
        /// </summary>
        /// <exception cref="UnauthorizedException">
        /// throws UnauthorizedException if does not have ADMIN permissions
        /// </exception>
        /// <remarks>
        /// each forum can have an arbitrary number of extended properties. 
        /// This allows for enhanced functionality that is not part of 
        /// the base interface.
        /// </remarks>
        String Property { get; set; }


        /// <summary>
        /// Returns an Enumeration of all the names of the forum properties.
        /// </summary>
        /// <returns>
        /// return an Enumeration of all the names of the forum properties.
        /// </returns>
        Enumeration PropertyNames();

        /// <summary>
        /// if this forum is moderated
        /// </summary>
        /// <exception cref="UnauthorizedException">
        /// throws UnauthorizedException if does not have ADMIN permissions.
        /// </exception>
        /// <remarks>
        /// Returns or sets whether  this forum is moderated. When a forum is moderated,
        /// posted messages and threads must first be approved by a user with
        /// moderator permissions.
        /// </remarks>
        bool IsModerated { get; set; }


        /// <summary>
        /// Factory method to create a Thread.
        /// </summary>
        /// <param name="rootMessage">the root message of the thread.</param>
        /// <param name="type"></param>
        /// <returns>ForumThread</returns>
        /// <exception cref="UnauthorizedException">
        /// throws UnauthorizedException if does not have CREATE_THREAD permissions.
        /// </exception>
        ForumThread CreateThread(ForumMessage rootMessage, ThreadType type);//abstract

 
        /// <summary>
        /// Factory method to create a Message.
        /// </summary>
        /// <param name="user">the user for the message.</param>
        /// <param name="clientIP">client IP</param>
        /// <returns>ForumMessage</returns>
        /// <exception cref="UnauthorizedException,RapidPostingException,UserBlackListedException">
        /// </exception>
        ForumMessage CreateMessage(User user, ClientIP clientIP);//abstract

        /// <summary>
        /// Factory method to create a Dummy Message. This is used to display how
        /// a message looks after it is filtered.
        /// </summary>
        /// <param name="user">the user for the message.</param>
        /// <returns><see cref="ForumMessage"/>ForumMessage</returns>
        /// <exception cref="UnauthorizedException">
        /// throws UnauthorizedException if does not have CREATE_MESSAGE permissions.
        /// </exception>
        ForumMessage CreateDummyMessage(User user);//abstract

        /// <summary>
        /// Adds a thread to the forum.
        /// </summary>
        /// <param name="thread">the thread to add to the forum.</param>
        /// <exception cref="UnauthorizedException">
        /// throws UnauthorizedException if does not have CREATE_THREAD permissions.
        /// </exception>
        void AddThread(ForumThread thread);

        /// <summary>
        /// Deletes a thread. Once a thread is deleted, the thread object should
        /// no longer be used.
        /// </summary>
        /// <param name="thread">the thread to delete.</param>
        /// <exception cref="UnauthorizedException">
        /// throws UnauthorizedException if does not have ADMIN permissions.
        /// </exception>
        void DeleteThread(ForumThread thread);

        /// <summary>
        /// Moves a thread from one forum to another.
        /// </summary>
        /// <param name="thread">the thread to move to another forum.</param>
        /// <param name="newForum">the forum to move the thread to.</param>
        /// <exception cref="UnauthorizedException">
        /// throws UnauthorizedException if does not have ADMIN permissions for the
        /// this forum and <code>newForum</code>.
        /// </exception>
        /// <exception cref="IllegalArgumentException">
        /// throws IllegalArgumentException if <code>thread</code> does not belong
        /// to the forum that this method was invoked on.
        /// </exception>
        /// <remarks>
        /// Moves a thread from one forum to another. For this to work, the thread
        /// must exist in the forum that this method is invoked on, and the user
        /// calling this method must have ADMIN permissions for the forum this method
        /// is invoked on and <code>newForum</code>.<p>
        /// The main purpose of this method is to allow admins to move non-topical
        /// threads into a more appropriate forum.
        /// </remarks>
        void MoveThread(ForumThread thread, Forum newForum);

        /// <summary>
        /// Returns the thread specified by id. The method will return null
        /// if the thread is not in the forum.
        /// </summary>
        /// <param name="threadID">thread ID</param>
        /// <returns><see cref="ForumThread"/>ForumThread</returns>
        /// <exception cref="ForumThreadNotFoundException">
        /// throws ForumThreadNotFoundException;
        /// </exception>
        ForumThread getThread(int threadID);

        /// <summary>
        /// Returns a Iterator for the forum to move through the threads.
        /// </summary>
        /// <returns></returns>
        Iterator Threads();


        /// <summary>
        /// Returns a ListIterator for the forum to move through the threads.
        /// </summary>
        /// <param name="startIndex">he index you'd like to start the iterator at.</param>
        /// <param name="numResults"></param>
        /// <param name="sortBy">used to sort messages - create/modified date.</param>
        /// <returns></returns>
        Iterator Threads(int startIndex, int numResults, int sortBy);

        /// <summary>
        /// Returns the number of threads in the forum.
        /// </summary>
        /// <returns></returns>
        int GetThreadCount();

        /// <summary>
        /// Returns the number of messages in the forum.
        /// </summary>
        /// <returns></returns>
        int GetMessageCount();


        /// <summary>
        /// Creates a query object to search the forum. This method is considered
        /// a first stab at searching in Yazd, and will almost certainly be
        /// modified in the near future.
        /// </summary>
        /// <returns></returns>
        Query CreateQuery();

        /// <summary>
        /// Grants a user a particular permission for the forum. Valid permission
        /// types for a forum are <code>ForumPermissions.ADMIN</code>
        /// </summary>
        /// <param name="user">the User to grant a permission to.</param>
        /// <param name="permissionType">he type of permission to grant the user.</param>
        /// <exception cref="UnauthorizedException">
        /// throws UnauthorizedException if does not have ADMIN permissions.
        /// </exception>
        void AddUserPermission(User user, int permissionType);//  throws UnauthorizedException;

        /// <summary>
        /// Revokes a particular permission from a user for the forum.
        /// </summary>
        /// <param name="user">the User to revoke a permission from.</param>
        /// <param name="permissionType">the type of permission to revoke from the user.</param>
        /// <exception cref="UnauthorizedException">
        /// throws UnauthorizedException if does not have ADMIN permissions.
        /// </exception>
        void RemoveUserPermission(User user, int permissionType);

        /// <summary>
        /// Returns all the userID's of users with a particular permission.
        /// </summary>
        /// <param name="permissionType">the type of permission to check.</param>
        /// <returns></returns>
        /// <exception cref="UnauthorizedException">
        /// throws UnauthorizedException if does not have ADMIN permissions.
        /// </exception>
        /// <see cref="ForumPermissions"/>
        int[] UsersWithPermission(int permissionType);

        /// <summary>
        /// Grants a group a particular permission for the forum.
        /// </summary>
        /// <param name="group"></param>
        /// <param name="permissionType">the type of permission.</param>
        /// <exception cref="UnauthorizedException">
        /// throws UnauthorizedException if does not have ADMIN permissions.
        /// </exception>
        /// <see cref="ForumPermissions"/>
        void AddGroupPermission(Group group, int permissionType);

        /// <summary>
        /// Revokes a particular permission from a group for the forum.
        /// </summary>
        /// <param name="group"></param>
        /// <param name="permissionType"></param>
        /// <exception cref="UnauthorizedException">
        /// throws UnauthorizedException if does not have ADMIN permissions.
        /// </exception>
        void RemoveGroupPermission(Group group, int permissionType);


        /// <summary>
        /// Returns all the groupID's of groups with a particular permission.
        /// </summary>
        /// <param name="permissionType">permissionType</param>
        /// <returns>groupID's</returns>
        /// <exception cref="throws UnauthorizedException;">
        /// throws UnauthorizedException if does not have ADMIN permissions.
        /// </exception>
        int[] GroupsWithPermission(int permissionType);


        /// <summary>
        /// Applies all of the currently active filters to a message.
        /// </summary>
        /// <param name="message">the ForumMessage to apply filters to.</param>
        /// <returns></returns>
        ForumMessage ApplyFilters(ForumMessage message);

        /// <summary>
        /// Returns an array of the currently active ForumMessageFilters.
        /// </summary>
        /// <returns>ForumMessageFilter</returns>
        /// <exception cref="UnauthorizedException">
        /// throws UnauthorizedException if does not have ADMIN permissions.
        /// </exception>
        ForumMessageFilter[] GetForumMessageFilters();


        /// <summary>
        /// Adds a new ForumMessageFilter to the end of the filter list.
        /// </summary>
        /// <param name="filter">ForumMessageFilter to add to the filter list.</param>
        /// <exception cref="UnauthorizedException">
        /// 
        /// </exception>
        void AddForumMessageFilter(ForumMessageFilter filter);

        /// <summary>
        /// Inserts a new ForumMessageFilter at specified index in the filter list.
        /// </summary>
        /// <param name="filter">ForumMessageFilter to add to the filter list.</param>
        /// <param name="index">position in filter list to insert new filter.</param>
        /// <exception cref="UnauthorizedException">
        /// 
        /// </exception>
        void AddForumMessageFilter(ForumMessageFilter filter, int index);


        /// <summary>
        /// Removes a ForumMessageFilter at the specified index in the filter list.
        /// </summary>
        /// <param name="index">
        /// index position in filter list to remove filter from.
        /// </param>
        /// <exception cref="UnauthorizedException">
        /// throws UnauthorizedException if does not have ADMIN permissions.
        /// </exception>
        void RemoveForumMessageFilter(int index);

        /// <summary>
        /// Returns the permissions for the forum that correspond to the
        /// passed-in Authorization.
        /// </summary>
        /// <param name="authorization">
        /// the auth token to lookup permissions for.
        /// </param>
        /// <returns></returns>
        ForumPermissions GetPermissions(Authorization authorization);//abstract

        /// <summary>
        /// Returns true if the handle on the object has the permission specified.
        /// A list of possible permissions can be found in the ForumPermissions
        /// class. Certain methods of this class are restricted to certain
        /// permissions as specified in the method comments.
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        /// <see cref="ForumPermissions"/>
        bool HasPermission(int type);


        
        /// <summary>
        /// This method returns true if this forum is used for discussions around an article page.
        /// </summary>
        /// <returns>return true if this forum is for articles</returns>
        bool IsArticleForum();

        /// <summary>
        /// 
        /// </summary>
        /// <param name="pageKey"></param>
        /// <param name="thread"></param>
        /// <exception cref="UnauthorizedException">
        /// throws UnauthorizedException if does not have ADMIN permissions.
        /// </exception>
        void AddArticleMap(String pageKey, ForumThread thread);



        /// <summary>
        /// set the order number for the forum.
        /// </summary>
        /// <exception cref="UnauthorizedException">
        /// throws UnauthorizedException if does not have ADMIN permissions.
        /// </exception>
        int ForumOrder { get; set; }

    }
}